import java.util.HashMap;
import java.util.LinkedList;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Valdez
 */
public class List {
 
    private String[] expresion;
    int index;
    boolean error;
    boolean termino;
    boolean salir;
    HashMap funciones;
    
    public List(String[] instru, HashMap funcionesActuales){
        expresion = instru;
        index = 0;
        termino = false;
        error = false;
        salir = false;
        funciones = funcionesActuales;
    }
    
    public void setExpresion(String[] instru){
        expresion = instru;
    }
    
    public String evaluar(){
        LinkedList lista = new LinkedList();
        String resultado="";
        double result;
        index++;
        if (expresion[index].equals("("))
            return evaluar();
        else{
            if (expresion[index].length() == 1){
                switch(expresion[index].charAt(0)){
                    case '+':
                        while (!expresion[++index].equals(")")){
                            if (expresion[index].equals("("))
                                lista.add(evaluar());
                            else
                                lista.add(expresion[index]);
                        }
                        result = 0;
                        result = lista.isEmpty()?result:Double.parseDouble((String)lista.remove());
                        while (!lista.isEmpty())
                            result += Double.parseDouble((String)lista.remove());
                        resultado=""+result;
                        break;
                    case '-':
                        while (!expresion[++index].equals(")")){
                            if (expresion[index].equals("("))
                                lista.add(evaluar());
                            else
                                lista.add(expresion[index]);
                        }
                        result = 0;
                        result = lista.isEmpty()?result:Double.parseDouble((String)lista.remove());
                        while (!lista.isEmpty())
                            result -= Double.parseDouble((String)lista.remove());
                        resultado=""+result;
                        break;
                    case '*':
                        while (!expresion[++index].equals(")")){
                            if (expresion[index].equals("("))
                                lista.add(evaluar());
                            else
                                lista.add(expresion[index]);
                        }
                        result = 0;
                        result = lista.isEmpty()?result:Double.parseDouble((String)lista.remove());
                        while (!lista.isEmpty())
                            result *= Double.parseDouble((String)lista.remove());
                        resultado=""+result;
                        break;
                    case '/':
                        while (!expresion[++index].equals(")")){
                            if (expresion[index].equals("("))
                                lista.add(evaluar());
                            else
                                lista.add(expresion[index]);
                        }
                        result = 0;
                        result = lista.isEmpty()?result:Double.parseDouble((String)lista.remove());
                        while (!lista.isEmpty())
                            result /= Double.parseDouble((String)lista.remove());
                        resultado=""+result;
                        break;
                    default:
                        if (funciones.containsKey(expresion[index])){
                            Funcion function = (Funcion)funciones.get(expresion[index]);
                            String[] param = new String[function.getKeysLength()];
                            int cont = 0;
                            while (!expresion[++index].equals(")")){
                                param[cont++] = expresion[index];
                            }
                            return function.llamarFuncion(param, funciones);
                        }
                        else
                            return "Esa expresion no existe";
                }
                return resultado;
            }
            else{ // no es una operacion aritmética
                if (funciones.containsKey(expresion[index])){
                    Funcion function = (Funcion)funciones.get(expresion[index]);
                    String[] param = new String[function.getKeysLength()];
                    System.out.println(function.getKeysLength());
                    int cont = 0;
                    while (!expresion[++index].equals(")")){
                        param[cont++] = expresion[index];
                    }
                    return function.llamarFuncion(param, funciones);
                }
                else
                    if (expresion[index].equals("EXIT"))
                        resultado = "(EXIT)";
                
                return resultado;
            }
        }
    }
    
}